import {
    Canvas,
    CanvasWidth,
    CanvasHeight,
} from "./components/canvas.js";
import { TikTok, tankStore, playerChance } from "./components/utils.js";
import { generateMap1 } from "./components/map.js";
import { Tank } from "./components/tank.js";
import { RobotController } from "./components/robot.js";

let player1;
let player2;
let _mainTik;
let _gameMap;
let _startState;
function _keydownListener(event) {
    let _controlKey = true;
    switch(event.keyCode) {
    case 87: player1.onEvent("keydown", "up");          // W
        break;
    case 83: player1.onEvent("keydown", "down");        // S
        break;
    case 65: player1.onEvent("keydown", "left");        // A
        break;
    case 68: player1.onEvent("keydown", "right");       // D
        break;
    case 32: player1.onEvent("keydown", "fire");        // SPACE
        break;
    case 38: player2.onEvent("keydown", "up");          // UP ARROW
        break;
    case 40: player2.onEvent("keydown", "down");        // DOWN ARROW
        break;
    case 37: player2.onEvent("keydown", "left");        // LEFT ARROW
        break;
    case 39: player2.onEvent("keydown", "right");       // RIGHT ARROW
        break;
    case 13: player2.onEvent("keydown", "fire");        // ENTER
        break;
    default: _controlKey = false;
        break;
    }
    if (_controlKey) {
        event.preventDefault();
    }
}
function _keyupListener(event) {
    let _controlKey = true;
    switch(event.keyCode) {
    case 87: player1.onEvent("keyup", "up");          // W
        break;
    case 83: player1.onEvent("keyup", "down");        // S
        break;
    case 65: player1.onEvent("keyup", "left");        // A
        break;
    case 68: player1.onEvent("keyup", "right");       // D
        break;
    case 32: player1.onEvent("keyup", "fire");        // SPACE
        break;
    case 38: player2.onEvent("keyup", "up");          // UP ARROW
        break;
    case 40: player2.onEvent("keyup", "down");        // DOWN ARROW
        break;
    case 37: player2.onEvent("keyup", "left");        // LEFT ARROW
        break;
    case 39: player2.onEvent("keyup", "right");       // RIGHT ARROW
        break;
    case 13: player2.onEvent("keyup", "fire");        // ENTER
        break;
    default: _controlKey = false;
        break;
    }
    if (_controlKey) {
        event.preventDefault();
    }
}

function begain() {
    destroy();
    init();
}
function init() {
    _gameMap = generateMap1();
    player1 = new Tank({
        parent: {
            getType: function() {
                return "player";
            },
        },
        name: "player1",
        type: "normalPlayer",
        coord: _gameMap.getPlayerCoord("player1"),
        beShotCb: byBullet => {
            if (byBullet.parent.parent && byBullet.parent.parent.getType() === "robot") {
                // 被robot击中
                if (player1.attr.blood === 2 && byBullet.power === 1) {
                    player1.switchType("normalPlayer");
                } else {
                    // 被击毁
                    player1.destroy().then(() => {
                        if (playerChance.player1 > 0) {
                            playerChance.player1--;
                            player1.reset();
                            tankStore.push(player1);
                        } else {
                            // 命花完了
                            _gameMap.showNoChanceTip("player1");
                        }
                    });
                }
            } else {
                // 被玩家击中没反应
            }
        },
    });

    player2 = new Tank({
        parent: {
            getType: function() {
                return "player";
            },
        },
        name: "player2",
        type: "normalPlayer",
        coord: _gameMap.getPlayerCoord("player2"),
        beShotCb: byBullet => {
            if (byBullet.parent.parent && byBullet.parent.parent.getType() === "robot") {
                // 被robot击中
                if (player2.attr.blood === 2 && byBullet.power === 1) {
                    player2.switchType("normalPlayer");
                } else {
                    // 被击毁
                    player2.destroy().then(() => {
                        if (playerChance.player2 > 0) {
                            playerChance.player2--;
                            player2.reset();
                            tankStore.push(player2);
                        } else {
                            // 命花完了
                            _gameMap.showNoChanceTip("player2");
                        }
                    });
                }
            } else {
                // 被玩家击中没反应
            }
        },
    });
    tankStore.push(player1, player2);

    RobotController.init();
    Canvas.init();              // 启动canvas

    document.addEventListener("keydown", _keydownListener);
    document.addEventListener("keyup", _keyupListener);

    // 启动帧渲染器
    function render() {
        let tankCoords = tankStore.map(_tank => {
            let { x, y } = _tank.coord;
            return _tank.attr.shape.map(graph => {
                let _arr = graph.map(item => [item[0] + x, item[1] + y]);
                _arr.opt = graph.opt;
                return _arr;
            });
        });
        let tankBulletCoords = tankStore.map(_tank => {
            return _tank._bulletStore.reduce((acc, _bullet) => {
                let { x, y } = _bullet.coord;
                let _bulletShapes = _bullet.shape.map(graph => {
                    let _arr = graph.map(item => [item[0] + x, item[1] + y]);
                    _arr.opt = graph.opt;
                    return _arr;
                });
                acc.push(..._bulletShapes);
                return acc;
            }, []);
        });

        let graphics = [
            ..._gameMap.getMap(),
        ];
        tankCoords.forEach(coord => {
            graphics.push(...coord);
        });
        tankBulletCoords.forEach(coord => {
            graphics.push(...coord);
        });
        Canvas.draw(graphics);
        _mainTik = requestAnimationFrame(render);
    }
    _mainTik = requestAnimationFrame(render);

    _startState = true;
    TikTok.init();      // 启动定时器
}

function start() {
    if (!_startState) {
        _startState = true;
        TikTok.init();
    }
}
function stop() {
    if (_startState) {
        _startState = false;
        TikTok.stop();
    }
}
function destroy() {
    TikTok.destroy();
    cancelAnimationFrame(_mainTik);

    document.removeEventListener("keydown", _keydownListener);
    document.removeEventListener("keyup", _keyupListener);

    Canvas.destroy();
    RobotController.destroy();

    player1 = null;
    player2 = null;
    tankStore.length = 0;

    _gameMap && _gameMap.destroy();
    _startState = false;
}

document.addEventListener("DOMContentLoaded", function() {
    document.querySelector("#playground").setAttribute("width", CanvasWidth);
    document.querySelector("#playground").setAttribute("height", CanvasHeight);
    document.querySelector("#begain").addEventListener("click", function() {
        begain();
    });
    document.querySelector("#start").addEventListener("click", function() {
        start();
    });
    document.querySelector("#stop").addEventListener("click", function() {
        stop();
    });
    setTimeout(() => {
        init();
    }, 200);
});

window.measureGrids = {
    inited: false,
    display: false,
    mark: 5 * 4,
    init() {
        if (!this.inited) {
            let width = document.querySelector("#playground").clientWidth;
            let height = document.querySelector("#playground").clientHeight;
            const tbody = document.querySelector("#measureGrids");
            tbody.style.width = width;
            tbody.style.height = height;

            let trStr = "";
            for (let i = 0; i < Math.round(height / this.mark); i++) {
                trStr += `<div>${"<span></span>".repeat(Math.round(width / this.mark))}<span>${(i + 1) * 5}</span></div>`;
            }
            let lastTrStr = "";
            for (let i = 0; i < Math.round(width / this.mark); i++) {
                lastTrStr += `<span>${(i + 1) * 5}</span>`;
            }
            lastTrStr = `<div>${lastTrStr}<span>0</span></div>`;
            tbody.innerHTML = `${trStr}${lastTrStr}`;

            this.inited = true;
        }
    },
    show() {
        if (this.display) {
            return true;
        }
        this.init();
        document.querySelector("#measureGrids").style.display = "block";
        this.display = true;
    },
    hide() {
        if (!this.display) {
            return true;
        }
        document.querySelector("#measureGrids").style.display = "none";
        this.display = false;
    },
};
window.showGrids = function () {};
window.closeGrids = function () {};
